<template>
	<div :class="$style['unity-map-wrapper']" :id="mapInfo.id">
		<div ref="bnMapRef" :class="$style['unity-map-container']" id="bn_map_id"></div>
		<DialogDahuaPlayer ref="refDialogDahuaPlayer" />
	</div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { loadScript } from '@/utils'
import { fetchMarkerCreate, fetchRemoveMarkerById, fetchMapMarker, fetchSetMaptZoom } from '@/api/map.services'
import { ElMessage } from "element-plus"
import DialogDahuaPlayer from '@/components/DialogDahuaPlayer.vue'
import CyMapBNPlugin from '@/utils/bn.map.class'

const props = defineProps({
	//地图数据
	useOperation: {
		type: Boolean,
		default: () => false
	}
})

/**
 * 父组件暴露的方法
 * 用户和父组件数据交互
 * defineEmits
 * 1:
 * 2:点击网格的操作
 * 3:图层移动后更新点位信息
 */
const changeMapEmit = defineEmits([
	"childChangeMap",
	"clickGird",
	"gridModifyEnd1",
	"clickMap",
	"loadingMarkers",
	"addRepairOrder",
	"openMarkerInfo"
])

let mapClass = new CyMapBNPlugin({
	useOperation: props.useOperation,
	onDomMarkerClick: (event, feature, coords) => {
		console.log('🚀[ ][ event ] =>', event)
		console.log('🚀[ ][ feature, coords ] =>', feature, coords)
	},
	onClick: (e, features) => {
		if (features.length > 0) {
			// changeMapEmit("clickMap", features[0])
			console.log('🚀[ ][ e, features ] =>', '点位点击事件')
			console.log('🚀[ ][ e, features ] =>', features)
			changeMapEmit("openMarkerInfo", features[0]?.properties)
		}
	},
	// 右键菜单
	onContextMenu: (command, data, marker, finalCoords) => {
		switch (command) {
			case 'delete':
				deleteMarker(data.id)
				break;

			default:
				break;
		}
	},
	// 拖动结束
	onDragEnd: (coords, marker, data) => {
		console.log('🚀[ ][ onDragEnd ][ coords, marker, data ] =>', coords, marker, data)
		const postData = {
			type: data.type,
			name: data.name,
			device_id: data.device_id,
			map_id: data.map_id,
			x: coords[0],
			y: coords[1],
			id: data.id,
			range: data.range
		}

		fetchMarkerCreate(postData).then((res) => {
			if (res.code == 1) {
				ElMessage.success("更新成功")
			}
		})
	}
})

let map
const mapInfo = ref({})
const settings = ref({})
let featureLayerId = "标准地址__GISPortal"
let edit
let draw
var currentFeature = null
let isMouseDown
let isDragging
let startLngLat
onMounted(() => {

})

const markerCenter = ref([])
const initBnMap = async (data, config) => {
	if (map) map.remove()
	settings.value = config
	mapInfo.value = data
	try {
		//首先加载加载博能地图js类库
		const src = `${data.map_file}/BNMap.umd.js?appSecret=${data.appSecret}&appkey=${data.appKey}`
		// await loadScript(src, 'BNMapJS')

		await mapClass.loadBnScript(src)

		//开始加载地图
		try {
			map = await mapClass.initMap(data, config)
			// map = await loadBNMap(data)
			//开始地图加载完成之后的回调
			complete()

			// initContentMenu()
		} catch (error) {
			console.error('地图加载失败', error)
		}
	} catch (err) {
		console.error(err)
	}
}

/**
 * @description 地图加载完成加载点位
 * @returns
 * */
const markers = ref([])
const complete = async () => {
	//加载点位
	const result = await fetchMapMarker(mapInfo.value.id, 0)
	console.log('🚀[ ][ complete ][ result ] =>', result)
	if (result.code == 1) {
		markers.value = result.data.data

		if (props.useOperation) {
			// 可拖拽点位使用 appendDomMarkers
			mapClass.appendDomMarkers(result.data.data, true)
		} else {
			// 纯展示点位使用 appendMarkers
			mapClass.appendMarkers(result.data.data, true)
		}

		// setTimeout(() => {
		// 	// 开启编辑模式
		// 	mapClass.startEditMode()
		// }, 2000)

		// loadingPoints()
	}
	// loadingPointMove()
	// loadingdDrawEvent()
	//开启鼠标移动事件
	// if (settings.value.is_move) {
	// 	// loadingPointMove()
	// 	loadingdDrawEvent()
	// 	// loadingMapClick()
	// }
}

/**
 * @description 设置点位名称显示隐藏
 * @param {*} options
 */
const setFeatureName = (is_open) => {
	mapClass.visibleText(is_open)
}

/**
 * 根据类型和关键字，筛选需要显示的节点
 * @param {Number[]} types   显示的类型 [1:视频监控,2:公共广播,3:辅助灯光,4:围界防区,5:围界光纤,6:其他设备]
 * @param {String}   keyword 搜索的关键字
 * @param {Function} reset 没有 keyword 时，重置显示的函数
 * @param {Boolean}  visible 根据 keyword 搜索时，是否显示节点
 */
function filterFeature({ subsystem, types, keyword = '', visible = true, visibleAlarm = true }) {
	const reg = keyword ? new RegExp(keyword) : null
	const cachePoints = mapClass.cachePoints || []

	const typeMap = types.reduce((map, id) => {
		map[id] = 1

		return map
	}, {})

	const visibleIds = cachePoints.reduce((ids, item) => {
		if (typeMap[item.subsystem_id]) {
			if (reg) {
				if (reg.test(item.name)) {
					ids.push(item.device_id)
				}
			} else {
				ids.push(item.device_id)
			}
		}

		return ids
	}, [])

	if (reg) {
		return mapClass.filterFeatures(visibleIds).map((item) => {
			item.data = window.structuredClone(item)
			return item
		})
	}

	mapClass.visibleFeatures(visibleIds)
}

/**
 * @description 移动到指定点位
 * @param {Object} feature
 * @param {Object} featureItem
 * @param {Boolean} visibleAlarm
 * */
function moveToFeature(feature, featureItem, visibleAlarm) {
	console.log('🚀[ ][ moveToFeature ][ featureItem ] =>', featureItem)
	mapClass.visiblePoint(featureItem.device_id)
	mapClass.moveToFeature(featureItem.device_id)
}

/**
 * @description 开启点位移动
 * @returns
 * */
const loadingPointMove = () => {
	// 鼠标按下事件
	map.on('mousedown', (e) => {
		isMouseDown = true
		const layerId = 'layer2'
		const features = map.queryRenderedFeatures(e.point, { layers: [layerId] })
		if (features.length > 0) {
			isDragging = true
			startLngLat = e.lngLat
			// 关键：阻止地图默认的鼠标按下行为（避免地图自己平移）
			e.preventDefault()
			e.stopPropagation()
		} else {
			isDragging = false
		}
		console.log('features', features)
		console.log('按下鼠标...', e)
	})
	// // 鼠标释放
	map.on('mouseup', (e) => {
		isMouseDown = false
		// isDragging = false
		console.log('鼠标释放...', e)
		markerCenter.value = [e.lngLat.lng, e.lngLat.lat]
		console.log('鼠标释放...', markerCenter.value)
	})
	// 鼠标悬停 【一般配置图层使用】
	// map.on('mouseover', (e) => {
	// 	console.log('鼠标悬停...', e)
	// })
	// 鼠标移动
	map.on('mousemove', (e) => {
		if (isMouseDown) {
			console.log('鼠标移动...', e)
		}
		if (isDragging) {
			console.log('鼠标开始移动')
			const layerId = 'layer2'
			const dx = e.lngLat.lng - startLngLat.lng
			const dy = e.lngLat.lat - startLngLat.lat
			// 获取当前数据源并更新点位坐标
			const source = map.getSource(layerId)
			const geojson = source._data // 获取当前GeoJSON数据（注意：博能地图可能用getSourceData()等方法，需参考文档）

			if (geojson?.features?.length) {
				// 更新要素坐标（累加偏移量）
				geojson.features[0].geometry.coordinates[0] += dx
				geojson.features[0].geometry.coordinates[1] += dy

				// 重新设置数据源，让地图刷新
				source.setData(geojson)
				console.log('鼠标开始移动', startLngLat)
				// 更新起始坐标（用于下一次移动计算）
				startLngLat = e.lngLat
			}
		}
	})
	// 鼠标离开地图区域：强制结束拖拽（避免异常状态）
	map.on('mouseout', () => {
		isDragging = false
		startLngLat = null
	})
}
const loadingMapClick = () => {
	map.on("click", ['points'], function name(e) {
		console.log("单击", e)
		// 获取点击的要素信息
		var features = map.queryRenderedFeatures(e.point, { layers: ['points'] })
		console.log(features)
	})
}
const loadingdDrawEvent = () => {

	draw = new BNMap.BNDraw({
		displayControlsDefault: false,
		controls: {
			//polygon: true, // 允许绘制多边形
			//trash: true // 允许删除
		}
	})
	map.addControl(draw, 'top-left')
	// 绘制完成事件
	map.on("draw.create", function name(params) {
		console.log("create", params)
		currentFeature = params.features[0]
	})
}

/**
 * @description 地图加载完成加载点位
 * @returns
 * */
const loadingPoints = async () => {
	if (markers.value.length == 0) {
		return
	}
	// await loadMarkers(map, markers.value)
}

/**
 * @description 添加地图点位
 * @param {*} data
 * @returns
 * */
const appendMarker = async (data) => {
	console.log(mapClass.currentCursorCoord)
	if (!mapClass.currentCursorCoord || mapClass.currentCursorCoord.length < 2) {
		console.error("获取点位坐标异常")
		return
	}

	const params = {
		type: data.node_id,
		name: data.device_name,
		device_id: data.id,
		map_id: mapInfo.value.id,
		x: mapClass.currentCursorCoord[0],
		y: mapClass.currentCursorCoord[1]
	}
	const result = await fetchMarkerCreate(params)

	if (result.code == 1) {
		ElMessage.success("添加成功")

		complete()
		changeMapEmit("loadingMarkers", {})
	}
}

const deleteMarker = async (id) => {
	const result = await fetchRemoveMarkerById(id)
	if (result.code == 1) {
		ElMessage.success("删除成功")

		complete()
		changeMapEmit("loadingMarkers", {})
	}
}

/**
 * @description 设置地图默认缩放
 * @param {*} command
 * @returns
 * */
const setMapZoom = async (command) => {
	const zoom = Number(map.getZoom().toFixed(2))
	let params = {
		id: mapInfo.value.id
	}
	switch (command) {
		case 'default':
			if (zoom == mapInfo.value.zoom) {
				ElMessage.warning('当前默认缩放层级和当前缩放层级一致，无需设置')
				return
			}
			params.zoom = zoom
			break
		case 'max':
			if (zoom == mapInfo.value.max_zoom) {
				ElMessage.warning('当前最大缩放层级和当前缩放层级一致，无需设置')
				return
			}
			params.max_zoom = zoom
			break
		case 'min':
			if (zoom == mapInfo.value.min_zoom) {
				ElMessage.warning('当前最小缩放层级和当前缩放层级一致，无需设置')
				return
			}
			params.min_zoom = zoom
			break
	}
	const result = await fetchSetMaptZoom(params)
	if (result.code == 1) {
		mapInfo.value.zoom = zoom
		// const config = {
		// 	id: 'map_manage',
		// 	type: 3,
		// 	eye_open: false
		// }
		// init(optionsinfo.value, config)
		ElMessage.success('设置成功')
	}
	console.log('zoom', zoom)
	const maxZoom = map.getMaxZoom()
	const minZoom = map.getMinZoom()
}
/**
 * @description 地图复位
 * @returns
 * */
const setPointCenter = () => {
	map.setPointCenter()
}
const markerdraw = () => {
	draw.changeMode('draw_point')
}
defineExpose({
	initBnMap,
	appendMarker,
	setMapZoom,
	markerdraw,
	setFeatureName,
	filterFeature,
	moveToFeature,
	setPointCenter
})
onBeforeUnmount(() => {
	mapClass = null
})
</script>
<style lang="scss" module>
.unity-map-wrapper,
.unity-map-container {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden
}
</style>

<style lang="scss">
.ol-overviewmap {
	right: unset;
	top: unset;
	left: 0.5em;
	bottom: 0.5em;
	width: 300px;
	height: 200px;

	.ol-overviewmap-map {
		width: 300px;
		height: 200px;
	}
}
</style>